package com.learnyou.server.xingzuo.biz.handle;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.learnyou.server.xingzuo.common.constants.BaseConstants;
import com.learnyou.server.xingzuo.dto.resultDTO.LoginResultDTO;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.sql.Timestamp;
import java.util.Objects;

@Component
public class DBMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        setCreateField(metaObject);
        setUpdateField(metaObject);
        setLogicalDeleteField(metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        setUpdateField(metaObject);
    }

    /**
     * set crete field
     * @param metaObject MetaObject
     */
    private void setCreateField(MetaObject metaObject) {
        Timestamp now = new Timestamp(System.currentTimeMillis());
        if (metaObject.hasSetter(BaseConstants.CREATED_AT)) {
            setFieldValByName(BaseConstants.CREATED_AT, now, metaObject);
        }
        if (metaObject.hasSetter(BaseConstants.CREATED_BY)) {
            setFieldValByName(BaseConstants.CREATED_BY, getUserName(), metaObject);
        }
    }

    /**
     * set update field
     * @param metaObject MetaObject
     */
    private void setUpdateField(MetaObject metaObject) {
        Timestamp now = new Timestamp(System.currentTimeMillis());
        if (metaObject.hasSetter(BaseConstants.UPDATED_AT)) {
            setFieldValByName(BaseConstants.UPDATED_AT, now, metaObject);
        }
        if (metaObject.hasSetter(BaseConstants.UPDATED_BY)) {
            setFieldValByName(BaseConstants.UPDATED_BY, getUserName(), metaObject);
        }
    }

    /**
     * 配置逻辑删除字段
     * @param metaObject MetaObject
     */
    private void setLogicalDeleteField(MetaObject metaObject) {
        boolean hasSetter = metaObject.hasSetter(BaseConstants.REMOVED);
        boolean isEmpty = ObjectUtils.isEmpty(getFieldValByName(BaseConstants.REMOVED, metaObject));
        if (hasSetter && isEmpty) {
            setFieldValByName(BaseConstants.REMOVED, false, metaObject);
        }
    }

    private String getUserName() {
        LoginResultDTO loginResultDTO = TokenContextUtil.getUserInfo();

        String username = Objects.nonNull(loginResultDTO) ? loginResultDTO.getLoginName() : BaseConstants.DEFAULT_OPT;
        return username;
    }
}
